package com.gitee.srurl.core.factory.handle;

import com.gitee.srurl.core.annotation.Order;
import com.gitee.srurl.core.dto.request.GenerateShortUrlDTO;
import com.gitee.srurl.core.dto.result.ShortUrlResultDTO;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author zxw
 * @date 2023/4/29 9:45
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GenerateShortUrlContext {

    private GenerateShortUrlWrapper handler;

    private final Map<String, IGenerateShortUrlHandle> generateShortUrlHandleMap;

    @PostConstruct
    private void init() {

        Map<Integer, IGenerateShortUrlHandle> handleMap = new TreeMap<>();
        for (Map.Entry<String, IGenerateShortUrlHandle> entry : generateShortUrlHandleMap.entrySet()) {
            IGenerateShortUrlHandle handle = entry.getValue();
            Order order = handle.getClass().getDeclaredAnnotation(Order.class);
            int index;
            if (order == null) {
                index = Integer.MAX_VALUE;
            } else {
                index = order.value();
            }
            handleMap.put(index, handle);
        }
        List<IGenerateShortUrlHandle> generateShortUrlHandles = new ArrayList<>();
        // 排好序的转list
        handleMap.forEach((key, value) -> generateShortUrlHandles.add(value));
        // 包装一下 IGenerateShortUrlHandle
        this.handler = new GenerateShortUrlWrapper(generateShortUrlHandles.get(0));
        // 尾节点
        GenerateShortUrlWrapper tail = this.handler;
        for (int i = 1; i < generateShortUrlHandles.size(); i++) {
            IGenerateShortUrlHandle generateShortUrlHandle = generateShortUrlHandles.get(i);
            tail = tail.nextHandle(generateShortUrlHandle);
        }
    }

    /**
     * 请求处理
     *
     * @param generateShortUrlDTO 生成短链的参数
     * @return 返回的结果
     */
    public ShortUrlResultDTO handle(GenerateShortUrlDTO generateShortUrlDTO) {

        handler.handle(generateShortUrlDTO);
        return this.buildResult(generateShortUrlDTO);
    }

    /**
     * 构造返回结果
     *
     * @param generateShortUrlDTO 生成短链的参数
     * @return 返回的结果
     */
    private ShortUrlResultDTO buildResult(GenerateShortUrlDTO generateShortUrlDTO) {

        ShortUrlResultDTO shortUrlResultDTO = new ShortUrlResultDTO();
        shortUrlResultDTO.setOriginUrl(generateShortUrlDTO.getOriginUrl());
        boolean success = generateShortUrlDTO.isSuccess();
        shortUrlResultDTO.setSuccess(success);
        shortUrlResultDTO.setDisabled(generateShortUrlDTO.isDisable());
        if (success) {
            shortUrlResultDTO.setShortUrl(generateShortUrlDTO.getShortUrl());
            shortUrlResultDTO.setTimes(generateShortUrlDTO.getTimes());
            shortUrlResultDTO.setRemainTimes(generateShortUrlDTO.getTimes());
            shortUrlResultDTO.setExpireTime(generateShortUrlDTO.getExpireTime());
        } else {
            shortUrlResultDTO.setErrorMsg(generateShortUrlDTO.getMsg());
            log.info("生成短链url失败:{},详细参数:{}", generateShortUrlDTO.getMsg(), generateShortUrlDTO);
        }

        return shortUrlResultDTO;
    }

    private static class GenerateShortUrlWrapper {

        private final IGenerateShortUrlHandle handle;

        private GenerateShortUrlWrapper nextHandle;

        public GenerateShortUrlWrapper(IGenerateShortUrlHandle handle) {
            this.handle = handle;
            this.nextHandle = null;
        }

        public GenerateShortUrlWrapper nextHandle(IGenerateShortUrlHandle nextHandle) {
            this.nextHandle = new GenerateShortUrlWrapper(nextHandle);
            return this.nextHandle;
        }

        public void handle(GenerateShortUrlDTO generateShortUrlDTO) {

            boolean continueHandle = handle.handle(generateShortUrlDTO);
            if (continueHandle && nextHandle != null) {
                // 继续执行后面的处理
                nextHandle.handle(generateShortUrlDTO);
            }
        }
    }
}
